﻿using BusinessLayer.DatabaseEntities;
using BusinessLayer.VDataEntities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BusinessLayer
{
    public class TrialBusiness
    {
        public static VDataEntity[] GetProjectCategories()
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var projectCategories = from pc in entities.ProjectCategory
                                        select new VDataEntity() { ID = pc.ID, Name = pc.Name };
                return projectCategories.ToArray();
            }
        }
        public static VTrial[] GetTrialList(long? cropID, long? productID, long? prouctCategoryID, long[] provinceIDs, TrialSiteStatus status)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                int intStatus = (int)status;
                if (intStatus == 0)//未开始
                {
                    var trialNotStart = from trial in entities.Trial
                                        join promoter in entities.Promoter on trial.PromoterID equals promoter.ID
                                        join province in entities.Province on trial.ProvinceID equals province.ID
                                        join prouct in entities.Product on trial.ProductID equals prouct.ID
                                        where !(from trialSite in entities.TrialSite select trialSite.TrialID).Contains(trial.ID)
                                        && (provinceIDs.Count() == 0 ? true : provinceIDs.Contains(trial.ProvinceID))
                                        && (cropID == null ? true : trial.CropID == cropID.Value)
                                        && (productID == null ? true : trial.ProductID == productID.Value)
                                         && (prouctCategoryID == null ? true : prouct.ProductCategory.ID == prouctCategoryID)
                                         && trial.Status != (int)(TrialStatus.Deleted)
                                        select new VTrial()
                                        {
                                            ID = trial.ID,
                                            CreatedDate = trial.CreateDate,
                                            SubmitDate = trial.SubmitDate,
                                            CompletedDate = trial.CompleteDate,
                                            Product = trial.ProductName,
                                            Province = province.Name,
                                            Crop = trial.CropName,
                                            Promoter = promoter.ChineseName,
                                            PromoterUserName = promoter.UserName,
                                            Status = trial.Status,
                                            IsCreatedByPromoter = trial.IsCreatedByPromoter
                                        };
                    return trialNotStart.OrderByDescending(t => t.CreatedDate).ToArray();
                }
                else
                {
                    var trialList = from trial in entities.Trial
                                    join promoter in entities.Promoter on trial.PromoterID equals promoter.ID
                                    join province in entities.Province on trial.ProvinceID equals province.ID
                                    join trialSite in entities.TrialSite on trial.ID equals trialSite.TrialID
                                    join prouct in entities.Product on trial.ProductID equals prouct.ID
                                    where trialSite.Status == intStatus
                                    && (provinceIDs.Count() == 0 ? true : provinceIDs.Contains(trial.ProvinceID))
                            && (cropID == null ? true : trial.CropID == cropID.Value)
                            && (productID == null ? true : trial.ProductID == productID.Value)
                            && (prouctCategoryID == null ? true : prouct.ProductCategory.ID == prouctCategoryID)
                                    select new VTrial()
                                    {
                                        ID = trialSite.ID,
                                        CreatedDate = trialSite.CreateDate,
                                        SubmitDate = trialSite.SubmitDate,
                                        CompletedDate = trialSite.CompleteDate,
                                        Product = trial.ProductName,
                                        Province = province.Name,
                                        Crop = trial.CropName,
                                        Promoter = promoter.ChineseName,
                                        PromoterUserName = promoter.UserName,
                                        Status = trialSite.Status.HasValue == true ? trialSite.Status.Value : 0,
                                        IsCreatedByPromoter = trial.IsCreatedByPromoter,
                                        TrialSiteName = trialSite.Address
                                    };
                    return trialList.OrderByDescending(t => t.CreatedDate).ToArray();
                }
            }
        }

        public static void ApproveTrials(long trialSiteID)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var trial = (from t in entities.TrialSite
                             where t.ID == trialSiteID
                             select t).FirstOrDefault();
                if (trial != null)
                {
                    trial.Status = (int)TrialSiteStatus.Completed;
                    trial.CompleteDate = DateTime.Now;
                    entities.SaveChanges();
                }
            }
        }

        public static void DisApproveTrials(long trialSiteID)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var trial = (from t in entities.TrialSite
                             where t.ID == trialSiteID
                             select t).FirstOrDefault();
                if (trial != null)
                {
                    trial.Status = (int)TrialSiteStatus.Working;
                    trial.SubmitDate = null;
                    trial.CompleteDate = null;
                    entities.SaveChanges();
                }
            }
        }

        public static VTrialCandidate[] GetTrialCandidateList(long[] provinceIDs)
        {
            using (TrialManagementEntities entity = new TrialManagementEntities())
            {
                var candidateList = from pp in entity.RPromoterProvince
                                    join promoter in entity.Promoter on pp.PromoterID equals promoter.ID
                                    join province in entity.Province on pp.ProvinceID equals province.ID
                                    where (provinceIDs.Count() == 0 ? true : provinceIDs.Contains(pp.ProvinceID)) && promoter.IsActive == true
                                    select new VTrialCandidate()
                                    {
                                        Province = new VDataEntity() { ID = province.ID, Name = province.Name },
                                        Promoter = new VPromoter() { ID = promoter.ID, ChineseName = promoter.ChineseName, IsActive = true, Name = promoter.UserName }
                                    };
                return candidateList.ToArray();
            }

        }

        public static void AssignTrialTask(VTrialGuide vTrialGuide, VTrialCandidate[] trialCandidateList, long adminID, long projectCategoryID, string ca, string fsm)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                TrialGuide trialGuide = new TrialGuide();
                trialGuide.Agentia = vTrialGuide.Agentia;
                trialGuide.CropID = vTrialGuide.CropID;
                trialGuide.CropName = vTrialGuide.CropName;
                trialGuide.CropCategory = vTrialGuide.CropCategory;
                trialGuide.Object = vTrialGuide.Object;
                trialGuide.Others = vTrialGuide.Others;
                trialGuide.ProductID = vTrialGuide.ProductID;
                trialGuide.ProductName = vTrialGuide.ProductName;
                trialGuide.Purpose = vTrialGuide.Purpose;
                trialGuide.SubCropCategory = vTrialGuide.SubCropCategory;
                entities.TrialGuide.Add(trialGuide);
                entities.SaveChanges();
                long trialGuideID = trialGuide.ID;

                foreach (VTrialCandidate trialCandidate in trialCandidateList)
                {
                    Trial trial = new Trial();
                    trial.ProvinceID = trialCandidate.Province.ID;
                    trial.ProductID = vTrialGuide.ProductID;
                    trial.ProductName = vTrialGuide.ProductName;
                    trial.CropID = vTrialGuide.CropID;
                    trial.CropName = vTrialGuide.CropName;
                    trial.PromoterID = trialCandidate.Promoter.ID;
                    trial.AssignDate = DateTime.Now;
                    trial.CreateDate = DateTime.Now;
                    trial.TTMID = adminID;
                    trial.ProjectCategoryID = projectCategoryID;
                    trial.CA = ca;
                    trial.FSM = fsm;
                    trial.TrialGuideID = trialGuideID;
                    trial.Status = (int)TrialSiteStatus.New;
                    trial.IsCreatedByPromoter = false;
                    entities.Trial.Add(trial);
                }

                entities.SaveChanges();
            }
        }

        public static VTrialDetail CreateNewTrial(long trialID)
        {
            VTrialDetail trialDetail = new VTrialDetail();

            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var trial = entities.Trial.Where(p => p.ID == trialID).First();
                trialDetail.ProductCategory = new VDataEntity() { ID = trial.Product.ProductCategory.ID, Name = trial.Product.ProductCategory.Name };
                trialDetail.TrialGuideID = trial.TrialGuideID == null ? 0 : trial.TrialGuideID;
                return trialDetail;
            }
        }

        public static VTrialDetail GetTrialDetail(long trialSiteID)
        {
            VTrialDetail trialDetail = new VTrialDetail();
            List<long> reportIDs = new List<long>();
            List<VReport> reportList = new List<VReport>();
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var trialSite = GetTrialSiteDetail(trialSiteID);
                var trial = entities.Trial.Where(p => p.ID == trialSite.TrialID).First();
                trialDetail.Province = trial.Province.Name;
                trialDetail.Promoter = trial.Promoter.ChineseName;
                trialDetail.PromoterUserName = trial.Promoter.UserName;
                trialDetail.CA = trial.CA;
                trialDetail.CompletedDate = trial.CompleteDate;
                trialDetail.CreatedDate = trial.CreateDate;
                trialDetail.Crop = trial.CropName;
                trialDetail.FSM = trial.FSM;
                trialDetail.Product = trial.ProductName;
                trialDetail.Status = trialSite.status;
                trialDetail.IsCreatedByPromoter = trial.IsCreatedByPromoter;
                trialDetail.SubmitDate = trial.SubmitDate;
                trialDetail.TrialGuideID = trial.TrialGuideID == null ? 0 : trial.TrialGuideID;
                trialDetail.ProductCategory = new VDataEntity() { ID = trial.Product.ProductCategory.ID, Name = trial.Product.ProductCategory.Name };
                if (trial.TTMID.HasValue)
                {
                    trialDetail.TTM = new VDataEntity() { ID = trial.Admin.ID, Name = trial.Admin.ChineseName };
                }
                if (trial.ProjectCategoryID.HasValue)
                {
                    trialDetail.ProjectCategory = new VDataEntity() { ID = trial.ProjectCategory.ID, Name = trial.ProjectCategory.Name };
                }

                trialDetail.TrialSite = trialSite;
                trialDetail.TrialSiteID = trialSiteID;
                trialDetail.TrialID = trialSite.TrialID;
                reportIDs = entities.Report.Where(p => p.TrialSiteID == trialSiteID).Select(p => p.ID).ToList();
            }
            foreach (long reportID in reportIDs)
            {
                VReport report = ReportBusiness.GetBasicReportInfo(reportID);
                reportList.Add(report);
            }
            trialDetail.Reports = reportList.ToArray();
            return trialDetail;
        }


        public static VTrial[] GetTrialByPromoterID(long promoterID)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var trialList = from trial in entities.Trial
                                join promoter in entities.Promoter on trial.PromoterID equals promoter.ID
                                join province in entities.Province on trial.ProvinceID equals province.ID
                                where trial.PromoterID == promoterID && trial.Status != (int)TrialStatus.Deleted
                                select new VTrial()
                                {
                                    ID = trial.ID,
                                    CreatedDate = trial.CreateDate,
                                    SubmitDate = trial.SubmitDate,
                                    CompletedDate = trial.CompleteDate,
                                    Product = trial.ProductName,
                                    Province = province.Name,
                                    Crop = trial.CropName,
                                    Promoter = promoter.ChineseName,
                                    PromoterUserName = promoter.UserName,
                                    Status = trial.Status,
                                    IsCreatedByPromoter = trial.IsCreatedByPromoter
                                };

                return trialList.OrderByDescending(o => o.CreatedDate).ToArray();
            }

        }

        public static long CreateTrial(long cropID, string cropName, long productID, string productName, long provinceID, long promoterID)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                Trial trial = new Trial();
                trial.ProvinceID = provinceID;
                trial.ProductID = productID;
                trial.ProductName = productName;
                trial.CropID = cropID;
                trial.CropName = cropName;
                trial.PromoterID = promoterID;
                trial.CreateDate = DateTime.Now;
                trial.Status = (int)TrialSiteStatus.New;
                trial.IsCreatedByPromoter = true;
                entities.Trial.Add(trial);
                entities.SaveChanges();
                return trial.ID;
            }
        }

        public static VTrialGuide GetTrialGuide(long trialGuideID)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var TrialGuide = from trialGuide in entities.TrialGuide
                                 where trialGuide.ID == trialGuideID
                                 select new VTrialGuide()
                                 {
                                     ID = trialGuide.ID,
                                     Agentia = trialGuide.Agentia,
                                     CropCategory = trialGuide.CropCategory,
                                     CropName = trialGuide.CropName,
                                     CropID = trialGuide.CropID,
                                     Object = trialGuide.Object,
                                     Others = trialGuide.Others,
                                     ProductID = trialGuide.ProductID,
                                     ProductName = trialGuide.ProductName,
                                     Purpose = trialGuide.Purpose,
                                     SubCropCategory = trialGuide.SubCropCategory
                                 };
                return TrialGuide.FirstOrDefault();
            }
        }

        public static long FillBasicInfo(long trialID, VTrialBasicInfo basicInfo)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                TrialSite trial = new TrialSite();
                trial.TrialID = trialID;
                trial.Address = basicInfo.Address;
                trial.Partner = basicInfo.Partner;
                trial.Object = basicInfo.Object;
                trial.CropCategory = basicInfo.CropCategory;
                trial.SubCropCategory = basicInfo.SubCropCategory;
                trial.SeedMode = basicInfo.SeedMode;
                trial.IsClosed = basicInfo.IsClosed;
                trial.Status = (int)TrialSiteStatus.Working;
                trial.CreateDate = DateTime.Now;
                entities.TrialSite.Add(trial);
                entities.SaveChanges();
                return trial.ID;
            }
        }

        public static void UpdateAdminInfo(long trialID, long ttmID, string fsm, string ca, long projectCategoryID)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var trial = (from t in entities.Trial
                             where t.ID == trialID
                             select t).FirstOrDefault();
                if (trial != null)
                {
                    trial.TTMID = ttmID;
                    trial.FSM = fsm;
                    trial.CA = ca;
                    trial.ProjectCategoryID = projectCategoryID;
                    entities.SaveChanges();
                }
            }
        }

        public static VReportFieldInfo[] CheckTrialMandaryFields(long trialSiteID)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var notFilledMandaryFileds = from inputdata in entities.ReportInputData
                                             join reportinfo in entities.ReportInfo on inputdata.ReportInfoID equals reportinfo.ID
                                             join report in entities.Report on reportinfo.ReportID equals report.ID
                                             join inputField in entities.ReportlInputField on inputdata.ReportInputFieldID equals inputField.ID
                                             where report.TrialSiteID == trialSiteID && inputdata.IsMandary == true && string.IsNullOrEmpty(inputdata.Value)
                                             && report.IsActive == true && reportinfo.IsActive == true
                                             select new VReportFieldInfo { ReportName = report.Name, FieldName = inputField.Name, ID = inputdata.ReportInfoID };
                return notFilledMandaryFileds.ToArray();
            }
        }

        public static void CompleteTrial(long trialSiteID, DateTime lastObserveDate, string effectResult, string effectDescription, bool isAcceptable, string comments, string yieldsEffert, string cropDescription)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var trial = (from t in entities.TrialSite
                             where t.ID == trialSiteID
                             select t).FirstOrDefault();
                if (trial != null)
                {
                    trial.LastObserveDate = lastObserveDate;
                    trial.EffectResult = effectResult;
                    trial.EffectDescription = effectDescription;
                    trial.Comments = comments;
                    trial.IsAcceptable = isAcceptable;
                    trial.YieldsEffert = yieldsEffert;
                    trial.CropDescription = cropDescription;

                    trial.Status = (int)TrialSiteStatus.Submitted;
                    trial.SubmitDate = DateTime.Now;

                    entities.SaveChanges();
                }
            }

        }

        public static VTrialSite[] GetTrialSiteByTrialID(long trialID)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var trialSite = from ts in entities.TrialSite
                                where ts.TrialID == trialID && ts.Status != (int)TrialSiteStatus.Deleted
                                select new VTrialSite { Address = ts.Address, ID = ts.ID, TrialID = ts.TrialID, status = ts.Status.HasValue ? ts.Status.Value : 0 };
                return trialSite.ToArray();
            }
        }

        public static VTrialSite GetTrialSiteDetail(long trialSiteID)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var trialSite = entities.TrialSite.Where(t => t.ID == trialSiteID).First();

                VTrialSite trialSiteDetail = new VTrialSite()
                {
                    Address = trialSite.Address,
                    SubCropCategory = trialSite.SubCropCategory,
                    CropCategory = trialSite.CropCategory,
                    SeedMode = trialSite.SeedMode,
                    Partner = trialSite.Partner,
                    Object = trialSite.Object,
                    IsClosed = trialSite.IsClosed,
                    Comments = trialSite.Comments,
                    YieldEffect = trialSite.YieldsEffert,
                    LastObserveDate = trialSite.LastObserveDate,
                    IsAcceptable = trialSite.IsAcceptable,
                    EffectResult = trialSite.EffectResult,
                    CropDescription = trialSite.CropDescription,
                    EffectDescription = trialSite.EffectDescription,
                    ID = trialSite.ID,
                    TrialID = trialSite.TrialID,
                    status = trialSite.Status.HasValue == true ? trialSite.Status.Value : 0,
                    SubmitDate = trialSite.SubmitDate,
                    CreateDate = trialSite.CreateDate,
                    CompleteDate = trialSite.CompleteDate,
                };
                return trialSiteDetail;
            }
        }

        public static long GetTrialGuideIDByTrialID(long id)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                long? guideid = entities.Trial.Where(t => t.ID == id).First().TrialGuideID;
                return guideid == null ? 0 : guideid.Value;
            }
        }

        public static VTrial GetTrialByTrialID(long trialID)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var vtrial = (from trial in entities.Trial
                              where trial.ID == trialID
                              select new VTrial { CreatedDate = trial.CreateDate, Product = trial.ProductName, Province = trial.Province.Name, Crop = trial.CropName, PromoterUserName = trial.Promoter.UserName }).First();
                return vtrial;
            }
        }

        public static List<IGrouping<string, VReport>> GetAllTrialDataByProductStataus()
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var reportArray = (from product in entities.Product
                                   join trial in entities.Trial on product.ID equals trial.ProductID
                                   join trialSite in entities.TrialSite on trial.ID equals trialSite.TrialID
                                   where trial.Status != (int)TrialStatus.Deleted && trialSite.Status != (int)TrialSiteStatus.Deleted
                                   select new VReport { TrialSiteID = trialSite.ID, promoterUserName = trial.Promoter.UserName, CreatedDate = trialSite.CreateDate.Value }).GroupBy(t => t.promoterUserName).ToList();
                return reportArray;
            }
        }

        public static void DelTrial(long id)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var trial = (from t in entities.Trial where t.ID == id select t).FirstOrDefault();
                if (trial != null)
                {
                    trial.Status = (int)TrialStatus.Deleted;
                    trial.CompleteDate = DateTime.Now;
                    entities.SaveChanges();
                }
                else
                {
                    throw new Exception("Trial id " + id + " can not be delete.");
                }
            }
        }

        public static void DelTrialSite(long id)
        {
            using (TrialManagementEntities entities = new TrialManagementEntities())
            {
                var trial = (from t in entities.TrialSite where t.ID == id select t).FirstOrDefault();
                if (trial != null)
                {
                    trial.Status = (int)TrialSiteStatus.Deleted;
                    trial.CompleteDate = DateTime.Now;
                    entities.SaveChanges();
                }
                else
                {
                    throw new Exception("TrialSite id " + id + " can not be delete.");
                }
            }
        }
    }
}
